package com.leetao.netty.handler;

import com.leetao.netty.constant.NettyConstants;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * 简单的handler adapter
 *
 * @author 菅江晖
 * @date 2021/4/15 - 18:17
 */
public abstract class SimpleChannelAdapter implements ChannelHandler {

    /**
     * 接收消息
     * @param channel channel
     * @param msg 消息
     */
    public abstract void message(Channel channel, String msg);

    /**
     * 初始化
     * @param channel msg
     * @param fullRequest msg
     * @param params 参数
     */
    public abstract void init(Channel channel, FullHttpRequest fullRequest, Map<String, List<String>> params);


    @Override
    public void message(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        message(ctx.channel(), msg.text());
    }

    @Override
    public void init(ChannelHandlerContext ctx, FullHttpRequest fullRequest) {
        HttpHeaders headers = fullRequest.headers();
        String connection = headers.get("Connection");
        String upgrade = headers.get("Upgrade");
        boolean conditon = NettyConstants.WEB_SOCKET.equals(upgrade) && NettyConstants.UPGRADE.equals(connection);
        //如果不为ws请求
        if(!conditon) {
            return;
        }
        //获取参数前的路径
        String uri = StringUtils.substringBefore(fullRequest.uri(), "?");
        //获取参数
        Map<String, List<String>> params = new QueryStringDecoder(fullRequest.uri()).parameters();
        init(ctx.channel(), fullRequest,params);
        fullRequest.setUri(uri);
        ctx.fireChannelRead(fullRequest.retain());
    }

    @Override
    public void disconnected(ChannelHandlerContext ctx) {
        this.disconnected(ctx.channel());
    }


    public abstract void disconnected(Channel channel);
}
